package models

import (
	"fmt"
	"time"

	"github.com/astaxie/beego/orm"
	"strconv"
	"encoding/base64"
)

type LogBill struct {
	Id       int       `orm:"column(id);auto"`
	UserId   string    `orm:"column(user_id);size(8)" description:"用户ID"`
	AppId    int       `orm:"column(app_id)" description:"应用ID"`
	BillType int8      `orm:"column(bill_type)" description:"记录类型"`
	ProdCost int8      `orm:"column(prod_cost)" description:"物品类型[消耗]"`
	ProdGain int8      `orm:"column(prod_gain)" description:"物品类型[获得]"`
	Cost     int       `orm:"column(cost)" description:"费用"`
	Gain     int       `orm:"column(gain)" description:"获得"`
	Title    string    `orm:"column(title);size(100)" description:"详情"`
	BillDate time.Time `orm:"column(bill_date);type(datetime)" description:"日期"`
}

type GiftList struct {
	Nickname string
	LogBill
}

func (t *LogBill) TableName() string {
	return "log_bill"
}

func init() {
	orm.RegisterModel(new(LogBill))
}

func AddLog(userId string,appId int,itemType int,num int,reason string) error{
	o := orm.NewOrm()
	var logBill LogBill

	logBill.UserId = userId
	logBill.AppId = appId
	logBill.BillType = 4
	logBill.ProdCost = 0
	logBill.ProdGain = int8(itemType)
	logBill.Cost = 0
	logBill.Gain = num
	logBill.Title = reason
	logBill.BillDate = time.Now()

	_, err := o.Insert(&logBill)
	if err != nil {
		fmt.Println("insert log_bill error",err)
		return err
	}
	return nil
}

func GetGiftList(page int,pageSize int,userId string,operateId int,operator string) ([]map[string]string,int64,map[int]map[string]string){
	o := orm.NewOrm()
	offset := (page - 1) * pageSize
	giftLists := make([]*GiftList,0)
	count := 0
	sqlStr := "select u.nickname,lb.* from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ? and bill_type = 4 order by bill_date desc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
	o.Raw(sqlStr,userId).QueryRows(&giftLists)
	sqlCount := "select count(*) from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ? and bill_type = 4"
	o.Raw(sqlCount,userId).QueryRow(&count)

	results := make([]map[string]string,0)
	for k,v := range giftLists{
		vip := "-"
		coin := "-"
		gift := "-"
		nickname,_ := base64.StdEncoding.DecodeString(v.Nickname)
		if v.ProdGain == 1 {
			coin = "+" + strconv.Itoa(v.Gain)
		}
		if v.ProdGain == 2 {
			gift = "+" + strconv.Itoa(v.Gain)
		}
		if v.ProdGain == 3 {
			vip = "+" + strconv.Itoa(v.Gain)
		}
		result := map[string]string{
			"sort":strconv.Itoa(k+1),
			"userId":userId,
			"nickname":string(nickname),
			"date":v.BillDate.Format("2006-01-02 15:04:05"),
			"operateId":strconv.Itoa(operateId),
			"operator":operator,
			"type":"赠送",
			"vip":vip,
			"coin":coin,
			"gift":gift,
			"reason":v.Title,
		}
		results = append(results, result)
	}

	tableHead := map[int]map[string]string{
		0:{"sort":"序号"},
		1:{"userId":"用户Id"},
		2:{"nickname":"用户名"},
		3:{"date":"发生时间"},
		4:{"type":"发生事由"},
		5:{"operateId":"操作员Id"},
		6:{"operator":"操作员"},
		7:{"vip":"Vip时长"},
		8:{"coin":"书币"},
		9:{"gift":"书券"},
		10:{"reason":"赠送事由"},
	}

	return results,int64(count),tableHead
}

func GetChangeList(page int,pageSize int,userId string,billType int8)([]map[string]string,int64,map[int]map[string]string){
	o := orm.NewOrm()
	offset := (page - 1) * pageSize
	giftLists := make([]*GiftList,0)
	count := 0
	if billType == 0 {
		sqlStr := "select u.nickname,lb.* from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ? order by bill_date desc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr,userId).QueryRows(&giftLists)
		sqlCount := "select count(*) from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ?"
		o.Raw(sqlCount,userId).QueryRow(&count)
	}else{
		sqlStr := "select u.nickname,lb.* from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ? and bill_type = ? order by bill_date desc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr,userId,billType).QueryRows(&giftLists)
		sqlCount := "select count(*) from user u inner join log_bill lb on(u.user_id = lb.user_id) where lb.user_id = ? and bill_type = ?"
		o.Raw(sqlCount,userId,billType).QueryRow(&count)
	}

	results := make([]map[string]string,0)
	for k,v := range giftLists{
		vip := 0
		coin := 0
		gift := 0
		recharge := 0
		if v.ProdCost == 1 {
			coin = coin - v.Cost
		}else if v.ProdCost == 2 {
			gift = gift - v.Cost
		}else if v.ProdCost == 5 {
			recharge = recharge - v.Cost
		}

		if v.ProdGain == 1 {
			coin = coin + v.Gain
		}else if v.ProdGain == 2 {
			gift = gift + v.Gain
		}else if v.ProdGain == 3 {
			vip = vip + v.Gain
		}

		nickname,_ := base64.StdEncoding.DecodeString(v.Nickname)
		result := map[string]string{
			"sort":strconv.Itoa(k+1),
			"userId":userId,
			"nickname":string(nickname),
			"date":v.BillDate.Format("2006-01-02 15:04:05"),
			"type":strconv.Itoa(int(v.BillType)),
			"vip":strconv.Itoa(vip),
			"coin":strconv.Itoa(coin),
			"gift":strconv.Itoa(gift),
			"recharge":strconv.Itoa(recharge),
			"reason":v.Title,
		}
		results = append(results, result)
	}

	tableHead := map[int]map[string]string{
		0:{"sort":"序号"},
		1:{"userId":"用户Id"},
		2:{"nickname":"用户名"},
		3:{"date":"发生时间"},
		4:{"type":"发生事由"},
		5:{"vip":"Vip时长"},
		6:{"coin":"书币"},
		7:{"gift":"书券"},
		8:{"recharge":"人民币"},
		9:{"reason":"备注"},
	}

	return results,int64(count),tableHead
}

func GetAccountList(page int,pageSize int,userId string,operateId int,operator string) ([]map[string]string,int64,map[int]map[string]string){
	o := orm.NewOrm()
	offset := (page - 1) * pageSize
	giftLists := make([]*GiftList,0)
	count := 0
	if userId == ""{
		sqlStr := "select u.nickname,lb.* from user u inner join log_bill lb on(u.user_id = lb.user_id) order by bill_date desc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr).QueryRows(&giftLists)
		sqlCount := "select count(*) from user u inner join log_bill lb on(u.user_id = lb.user_id)"
		o.Raw(sqlCount).QueryRow(&count)
	}else {
		sqlStr := "select u.nickname,lb.* from user u inner join log_bill lb on(u.user_id = lb.user_id) and lb.user_id = ? order by bill_date desc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr,userId).QueryRows(&giftLists)
		sqlCount := "select count(*) from user u inner join log_bill lb on(u.user_id = lb.user_id) and lb.user_id = ?"
		o.Raw(sqlCount,userId).QueryRow(&count)
	}

	results := make([]map[string]string,0)
	for k,v := range giftLists{
		vip := 0
		coin := 0
		gift := 0
		recharge := 0

		if v.ProdCost == 1 {
			coin = coin - v.Cost
		}else if v.ProdCost == 2 {
			gift = gift - v.Cost
		}else if v.ProdCost == 5 {
			recharge = recharge - v.Cost
		}

		if v.ProdGain == 1 {
			coin = coin + v.Gain
		}else if v.ProdGain == 2 {
			gift = gift + v.Gain
		}else if v.ProdGain == 3 {
			vip = vip + v.Gain
		}
		nickname,_ := base64.StdEncoding.DecodeString(v.Nickname)
		result := map[string]string{
			"sort":strconv.Itoa(k+1),
			"userId":v.UserId,
			"nickname":string(nickname),
			"date":v.BillDate.Format("2006-01-02 15:04:05"),
			"operateId":strconv.Itoa(operateId),
			"operator":operator,
			"type":strconv.Itoa(int(v.BillType)),
			"vip":strconv.Itoa(vip),
			"coin":strconv.Itoa(coin),
			"gift":strconv.Itoa(gift),
			"recharge":strconv.Itoa(recharge),
			"reason":v.Title,
		}
		results = append(results, result)
	}

	tableHead := map[int]map[string]string{
		0:{"sort":"序号"},
		1:{"nickname":"用户名"},
		2:{"date":"发生时间"},
		3:{"operateId":"操作员Id"},
		4:{"operator":"操作员"},
		5:{"type":"发生事由"},
		6:{"vip":"Vip时长"},
		7:{"coin":"书币"},
		8:{"gift":"书券"},
		9:{"userId":"用户Id"},
		10:{"reason":"赠送事由"},
	}

	return results,int64(count),tableHead
}